﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using PloobsEngine.Loader;

namespace PloobsEngine.Modelo
{
    public class ComposedPartsModel : IModelo
    {

        public ComposedPartsModel()
        {
        }

        public void Serialize(System.Xml.XmlTextWriter textWriter)
        {   
        }
        public void DeSerialize(System.Xml.XmlNode node,EngineStuff engine)
        {            
        }

        private string _paralaxName = null;

        public string ParalaxName
        {
            get { return _paralaxName; }
            set { _paralaxName = value; }
        }

        private string _glowName = null;

        public string GlowName
        {
            get { return _glowName; }
            set { _glowName = value; }
        }

        private string _bumpName = null;

        public string BumpMapName
        {
            get { return _bumpName; }
            set { _bumpName = value; }
        }
        private string _specularName = null;

        public string SpecularMapName
        {
            get { return _specularName; }
            set { _specularName = value; }
        }

        public String DiffuseMapName
        {
            get { return textureName; }
            set { textureName = value; }
        }

        #region IModelo Members
        private String _name;          
        private ModelMesh mesh;
        private int index;                
        Matrix[] transf = null;
        Texture2D texture = null;
        Texture2D bump = null;
        Texture2D specular = null;
        Texture2D glow = null;
        Texture2D paralax = null;
        String textureName = null;

        public ComposedPartsModel(ModelInformation mi)
        {
            this.Name = mi.ModelName;
            this.mesh = mi.modelMesh;
            this.texture = mi.difuse;
            this.specular = mi.specular;
            this.bump = mi.normal;
            this.glow = mi.glow;
            this.paralax = null;
            this.InternalName = mi.ModelMeshName;
            this.index = -1;
        }

        public ComposedPartsModel(String name, int index, String texName)
        {
            this.InternalName = null;
            this.DiffuseMapName = texName;
            this._bumpName = null;
            this.Name = name;
            this.index = index;
        }
      
        public ComposedPartsModel(String name, int index, String texName,String bumpName)
        {
            this.InternalName = null;
            this.DiffuseMapName= texName;
            this._bumpName = bumpName;
            this.Name = name;
            this.index = index;
        }        

        public ComposedPartsModel(String fileName,int index)
        {
            this.InternalName = null;
            this.Name = fileName;
            this.index = index;
        }

        public void changeTexture(String textureName, TextureType type)
        {
            switch (type)
            {
                case TextureType.DIFFUSE:
                    this._name = textureName;
                    break;
                case TextureType.SPECULAR:
                    this._specularName = textureName;
                    break;
                case TextureType.BUMP:
                    this._bumpName = textureName;
                    break;
                case TextureType.GLOW:
                    this._specularName = textureName;
                    break;
                case TextureType.PARALAX:
                    this._paralaxName = textureName;
                    break;
                default:
                    throw new Exception("Invalid Buffer");
            }

            LoadModelo();
        }

        public void LoadModelo()
        {
            if (this.mesh == null)
            {
                this.mesh = EngineStuff.CustomContentManager.GetModelParts(Name, index);
            }

            if (transf == null)
            {
                int elements = EngineStuff.CustomContentManager.GetTransformationMatrix(Name).Length;
                this.transf = new Matrix[elements];

                for (int i = 0; i < elements; i++)
                {
                    transf[i] = Matrix.Identity;
                }
            }            
            
            if (!String.IsNullOrEmpty(textureName))
            {
                this.texture = EngineStuff.CustomContentManager.GetAsset<Texture2D>(textureName);
            }
            if (!String.IsNullOrEmpty(_bumpName))
            {
                this.bump = EngineStuff.CustomContentManager .GetAsset<Texture2D>(_bumpName);
            }
            if (!String.IsNullOrEmpty(_specularName))
            {
                this.specular = EngineStuff.CustomContentManager.GetAsset<Texture2D>(_specularName);
            }
            if (!String.IsNullOrEmpty(_glowName))
            {
                this.glow = EngineStuff.CustomContentManager.GetAsset<Texture2D>(_glowName);
            }
            if (!String.IsNullOrEmpty(_paralaxName))
            {
                this.paralax= EngineStuff.CustomContentManager.GetAsset<Texture2D>(_paralaxName);            
            }

            ModelBuilderHelper.Extract(mesh, out batchInformationS, out vertexBufferS, out indexBufferS);            
        }

        public object getModelTag()
        {
            return null;
        }

        public Microsoft.Xna.Framework.Graphics.ModelMesh[] getModelMeshes()
        {
            return new ModelMesh[] { mesh };
        }

        public Microsoft.Xna.Framework.Matrix[] getBonesTransformation()
        {
            return transf;
        }


        #endregion

        #region IModelo Members

        
        public Texture2D getTexture(TextureType type)
        {
            if (type == TextureType.DIFFUSE)
            {
                return this.texture;                                
            }
            else if (type == TextureType.BUMP)
            {
                return this.bump;
            }
            else if (type == TextureType.SPECULAR)
            {
                return this.specular;
            }
            else if (type == TextureType.GLOW)
            {
                return this.glow;
            }
            else if (type == TextureType.PARALAX)
            {
                return this.paralax;
            }
            else
            {
                return null;
            }
        }

        #endregion

        #region IModelo Members


        public BoundingSphere GetBoudingSphere()
        {
            return mesh.BoundingSphere;
        }

        #endregion

        #region IModelo Members      


        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }

        private string _internalName;
        public string InternalName
        {
            get
            {
                return _internalName;
            }
            set
            {
                this._internalName = value;
            }
        }

        #endregion

        #region IModelo Members

        BatchInformation[][] batchInformationS;
        VertexBuffer[] vertexBufferS;
        IndexBuffer[] indexBufferS;

        public int MeshNumber
        {
            get { return 1; }
        }

        public VertexBuffer GetVertexBuffer(int meshNumber)
        {
            return vertexBufferS[meshNumber];
        }

        public IndexBuffer GetIndexBuffer(int meshNumber)
        {
            return indexBufferS[meshNumber];
        }

        public BatchInformation[] GetBatchInformation(int meshNumber)
        {
            return batchInformationS[meshNumber];
        }

        #endregion

        #region IModelo Members


        public int GetParentBoneIndex(int meshNumber)
        {
            return mesh.ParentBone.Index;
        }

        #endregion
    }
}
